package zz.demo.springCloud.wechat.config;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.cp.api.impl.WxCpServiceApacheHttpClientImpl;
import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import zz.demo.springCloud.wechat.entity.WeChatApp;
import zz.demo.springCloud.wechat.handler.*;

import java.io.Serializable;

/**
 * Created by zhangz on 2017/11/8.
 */
@Component
public class WxCpServiceAdapter extends WxCpServiceApacheHttpClientImpl implements Cloneable,Serializable {
    @Value("${post.proxy.host}")
    public String host;
    @Value("${post.proxy.port}")
    public Integer port;
    @Autowired
    protected LogHandler logHandler;
    @Autowired
    protected NullHandler nullHandler;
    @Autowired
    private LocationHandler locationHandler;
    @Autowired
    private MenuHandler menuHandler;
    @Autowired
    private MsgHandler msgHandler;
    @Autowired
    private UnsubscribeHandler unsubscribeHandler;
    @Autowired
    private SubscribeHandler subscribeHandler;
    @Autowired
    private ImageHandler imageHandler;
    @Autowired
    private LinkHandler linkHandler;
    @Autowired
    private VideoHandler videoHandler;
    @Autowired
    private VoiceHandler voiceHandler;

    protected WxCpMessageRouter messageRouter;
    private WeChatApp weChatApp;

    /*
        仅供spring构造使用，其余情况不得使用。
     */
    public WxCpServiceAdapter(){}

    /*
        new 一个新的对象。
     */
    public WxCpServiceAdapter build(WeChatApp weChatApp){
        WxCpServiceAdapter wxCpServiceAdapter = new WxCpServiceAdapter();
        wxCpServiceAdapter.logHandler = this.logHandler;
        wxCpServiceAdapter.nullHandler = this.nullHandler;
        wxCpServiceAdapter.locationHandler = this.locationHandler;
        wxCpServiceAdapter.menuHandler = this.menuHandler;
        wxCpServiceAdapter.msgHandler = this.msgHandler;
        wxCpServiceAdapter.unsubscribeHandler = this.unsubscribeHandler;
        wxCpServiceAdapter.subscribeHandler = this.subscribeHandler;
        wxCpServiceAdapter.imageHandler = this.imageHandler;
        wxCpServiceAdapter.linkHandler = this.linkHandler;
        wxCpServiceAdapter.videoHandler = this.videoHandler;
        wxCpServiceAdapter.voiceHandler = this.voiceHandler;
        wxCpServiceAdapter.afterPropertiesSet(weChatApp,host,port);
        return wxCpServiceAdapter;
    }

    /*
        对象初始化
     */
    public void afterPropertiesSet(WeChatApp weChatApp,String host,Integer port){
        this.weChatApp = weChatApp;
        this.configStorage = convert(new WxCpInMemoryConfigStorage(),weChatApp,host,port);
        this.messageRouter = routerInit();
        this.initHttp();
    }

    /*
        判断是否为空
     */
    public boolean isNotEmpty(){
        return StringUtils.isNotEmpty(this.weChatApp.getAccessPath())&&StringUtils.isNotEmpty(this.weChatApp.getServiceId());
    }

    public boolean isEmpty(){
        return !isNotEmpty();
    }

    /*
            本对象的route，需要注意的是传入的是本对象值，如果更新了本对象，就要重新生成其route。
            下一步实现：如何异步。
         */
    public WxCpMessageRouter routerInit(){
        WxCpMessageRouter newRouter = new WxCpMessageRouter(this);

        // 记录所有事件的日志 （异步执行）
        newRouter.rule().handler(this.logHandler).next();

        // 自定义菜单事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.BUTTON_CLICK).handler(this.getMenuHandler()).end();

        // 点击菜单连接事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.BUTTON_VIEW).handler(this.nullHandler).end();

        // 关注事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_SUBSCRIBE).handler(this.getSubscribeHandler())
                .end();

        // 取消关注事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_UNSUBSCRIBE)
                .handler(this.getUnsubscribeHandler()).end();

        // 上报地理位置事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_LOCATION).handler(this.getLocationHandler())
                .end();

        // 接收地理位置消息
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_LOCATION)
                .handler(this.getLocationHandler()).end();

        // 扫码事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_SCAN).handler(this.getScanHandler()).end();

        //语音事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_VOICE)
                .handler(this.getVoiceHandler()).end();

        //图片事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_IMAGE)
                .handler(this.getImageHandler()).end();

        //视频事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_VIDEO)
                .handler(this.getVideoHandler()).end();

        //链接事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_LINK)
                .handler(this.getLinkHandler()).end();

        //文字事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_TEXT)
                .handler(this.getMsgHandler()).end();

        // 默认
//        newRouter.rule().async(false).handler(this.nullHandler).end();

        return newRouter;
    }

    /*
            类型转换
         */
    private WxCpInMemoryConfigStorage convert(WxCpInMemoryConfigStorage configStorage,WeChatApp weChatApp,String
            host,Integer port){
        configStorage.setCorpId(weChatApp.getCorpId());
        configStorage.setAgentId(weChatApp.getAgentId());
        configStorage.setCorpSecret(weChatApp.getSecret());
        configStorage.setToken(weChatApp.getToken());
        configStorage.setAesKey(weChatApp.getAesKey());
        configStorage.setHttpProxyHost(host);
        configStorage.setHttpProxyPort(port);
        return configStorage;
    }

    public WxCpMessageRouter getMessageRouter() {
        return this.messageRouter;
    }

    protected MenuHandler getMenuHandler() {
        return this.menuHandler;
    }

    protected SubscribeHandler getSubscribeHandler() {
        return this.subscribeHandler;
    }

    protected UnsubscribeHandler getUnsubscribeHandler() {
        return this.unsubscribeHandler;
    }

    protected AbstractHandler getLocationHandler() {
        return this.locationHandler;
    }

    protected MsgHandler getMsgHandler() {
        return this.msgHandler;
    }

    public LogHandler getLogHandler() {
        return this.logHandler;
    }

    public ImageHandler getImageHandler() {
        return this.imageHandler;
    }

    public LinkHandler getLinkHandler() {
        return this.linkHandler;
    }

    public VideoHandler getVideoHandler() {
        return this.videoHandler;
    }

    public VoiceHandler getVoiceHandler() {
        return this.voiceHandler;
    }

    protected AbstractHandler getScanHandler() {
        return null;
    }

    public WeChatApp getWeChatApp() {
        return weChatApp;
    }

    public void setWeChatApp(WeChatApp weChatApp) {
        this.weChatApp = weChatApp;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public void setPort(int port) {
        this.port = port;
    }

    @Override
    protected WxCpServiceAdapter clone() throws CloneNotSupportedException {
        return (WxCpServiceAdapter) super.clone();
    }
}
